package de.e2it3t.schulverwaltung.ui;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.jgoodies.validation.ValidationResult;
import com.jgoodies.validation.ValidationResultModel;
import com.jgoodies.validation.util.DefaultValidationResultModel;
import com.jgoodies.validation.view.ValidationResultViewFactory;
import de.e2it3t.schulverwaltung.App;
import de.e2it3t.schulverwaltung.data.Klasse;
import de.e2it3t.schulverwaltung.data.Schueler;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

/**
 * Dialog für das Hinzufügen oder Bearbeiten eines Schülers. <br>
 * <br>
 * Je nach verwendetem Konstruktor kann man einen Dialog zum Erstellen oder 
 * Bearbeiten eines bestehenden Schülers anzeigen.<br>
 * <br>
 * Der Dialog sammelt Daten zu einem Schüler. Wenn der Speichern-Button gedrückt
 * wird, werden die Daten validiert. Wenn die Eingaben ungültig sind oder der
 * Schüler bereits vorhanden ist, dann werden entsprechende Meldungen angezeigt.
 * Wenn die Eingaben korrekt sind, wird der Schüler in der Datenbank
 * gespeichert, der Dialog geschlossen und die View, welche den Dialog geöffnet
 * hat, aufgefordert, ihre Daten zu erneuern.
 * 
 * @author Viktor Reiser
 */
public class SchuelerDialog extends JDialog {
    
    private JButton saveButton;
    private JButton cancelButton;
    private JTextField vornameField;
    private JTextField nachnameField;
    private JComboBox klasseComboBox;
    
    private Schueler schueler;
    
    private Klasse [] klassen;
    private ValidationResultModel validationModel;
    private AppView owner;
    
    
    /**
     * Dialog zum Erstellen eines neuen Schülers.
     * 
     * @param owner View, welche den Dialog geöffnet hat
     */
    public SchuelerDialog(AppView owner) {
        // lege für den zu bearbeitenden Schüler eine ungpltige ID fest
        this(owner, 0);
    }
    
    /**
     * Dialog zum Bearbeiten eines bestehenden Schülers.
     * 
     * @param owner View, welche den Dialog geöffnet hat
     * @param schuelerId ID des Schülers; wenn die ID ungültig ist, wrid ein
     * Dialog zum Erstellen eines neuen Schülers angezeigt
     */
    public SchuelerDialog(AppView owner, int schuelerId) {
        setTitle("Neuer Schüler");
        setModal(true);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setMinimumSize(new Dimension(100, 100));
        
        this.owner = owner;
        
        if (schuelerId != 0) {
            schueler = App.getDatabase().getSchueler(schuelerId);
            
            if (schueler != null) {
                // ID ist korrekt, wir bearbeiten einen Schüler
                setTitle("Schüler bearbeiten");
            }
        }
        
        // vorhandene Klassen
        klassen = App.getDatabase().getKlassen().toArray(new Klasse [0]);
        
        // Modell, welches Validierungsfehler erhält und diese in eine
        // Liste im Dialog füllt
        validationModel = new DefaultValidationResultModel();
        
        setupUi();
    }
    
    /**
     * Dialog Komponenten erstellen.
     */
    private void setupUiComponents() {
        vornameField = new JTextField();
        nachnameField = new JTextField();
        klasseComboBox = new JComboBox(klassen);
        
        saveButton = new JButton("Speichern");
        saveButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                validateAndSave();
            }
        });
        
        cancelButton = new JButton("Abbrechen");
        cancelButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                // wir zerstören den Dialog einfach
                dispose();
            }
        });
    }
    
    /**
     * Fülle UI mit den Daten des zu berbeitenden Schülers (falls vorhanden).
     */
    private void setupSchueler() {
        if (schueler == null) {
            return;
        }
        
        vornameField.setText(schueler.getVorname());
        nachnameField.setText(schueler.getNachname());
        
        for (Klasse klasse : klassen) {
            if (schueler.getKlasseId() == klasse.getId()) {
                // wir suchen nach der Klasse des Schülers und selektieren diese
                // in der ComboBox
                klasseComboBox.setSelectedItem(klasse);
                break;
            }
        }
    }
    
    /**
     * Erstelle den Dialog.
     */
    private void setupUi() {
        setupUiComponents();
        setupSchueler();
        
        JPanel content = new JPanel();
        content.setBorder(new EmptyBorder(10, 10, 10, 10));
        content.setLayout(new FormLayout(
                "pref, 5px, pref, 5px, pref",
                "pref, 5px, pref, 5px, pref, 5px, pref, 15px, pref"));
        CellConstraints cc = new CellConstraints();
        
        // Liste der Validierungmeldungen erstellen
        JComponent errorList = ValidationResultViewFactory.createReportList(
                validationModel);
        errorList.setPreferredSize(new Dimension(10, 50));
        
        // Komponenten im Dialog positionieren
        
        content.add(new JLabel("Vorname"), cc.xy(1, 1));
        content.add(vornameField, cc.xywh(3, 1, 3, 1));
        content.add(new JLabel("Nachname"), cc.xy(1, 3));
        content.add(nachnameField, cc.xywh(3, 3, 3, 1));
        content.add(new JLabel("Klasse"), cc.xy(1, 5));
        content.add(klasseComboBox, cc.xywh(3, 5, 3, 1));
        content.add(errorList, cc.xywh(1, 7, 5, 1));
        content.add(saveButton, cc.xy(3, 9));
        content.add(cancelButton, cc.xy(5, 9));
        
        setLayout(new BorderLayout());
        add(content, BorderLayout.CENTER);
        
        // gewünschte Größe des Dialog berechnen und setzen
        pack();
        // Dialog ist auf eine Größe fixiert
        setResizable(false);
        // Dialog in die Mitte des Bildschirms bringen
        setLocationRelativeTo(null);
    }
    
    private void validateAndSave() {
        ValidationResult result = new ValidationResult();
        Schueler saveSchueler = new Schueler();
        
        if (schueler != null) {
            saveSchueler.setId(schueler.getId());
        }
        
        saveSchueler.setVorname(vornameField.getText().trim());
        saveSchueler.setNachname(nachnameField.getText().trim());
        saveSchueler.setKlasseId(klassen[klasseComboBox.getSelectedIndex()].getId());
        
        if (saveSchueler.getVorname().equals("")) {
            result.addError("Vorname ist leer!");
        }
        if (saveSchueler.getNachname().equals("")) {
            result.addError("Nachname ist leer!");
        }
        if (App.getDatabase().hasSchueler(saveSchueler)) {
            result.addError("Schüler bereits vorhanden!");
        }
        
        validationModel.setResult(result);
        pack();
        
        if (result.isEmpty()) {
            // Schüler Angaben sind valide, speichern, schließen
            App.getDatabase().saveSchueler(saveSchueler);
            owner.refreshView();
            dispose();
        }
    }
}
